package com.ailight.smart.api.service.impl;

import cn.hutool.core.util.StrUtil;
import com.ailight.smart.api.config.Esp8266WifiConfig;
import com.ailight.smart.api.service.Esp8266WifiService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

@Service
@RequiredArgsConstructor
@Slf4j
public class Esp8266WifiServiceImpl implements Esp8266WifiService {
    private final Esp8266WifiConfig esp8266WifiConfig;

    @Override
    public void connectToConfiguredWifi() {
        if (StrUtil.isNotBlank(esp8266WifiConfig.getSsid())) {
            //去连接wife
            if (connectToWifi(esp8266WifiConfig.getSsid(),
                    esp8266WifiConfig.getPassword(), esp8266WifiConfig.getEncryption())) {
                log.info("esp8266-热点连接成功");
            } else {
                log.info("esp8266-热点连接失败");
            }
        }
    }

    @Override
    public boolean connectToWifi(String ssid, String password, String encryption) {
        try {
            Path xmlPath = generateWifiProfile(ssid, password, encryption);
            executeCommand("netsh wlan add profile filename=\"" + xmlPath + "\"");
            executeCommand("netsh wlan connect name=\"" + ssid + "\"");
            Files.deleteIfExists(xmlPath); // 删除临时文件
            return true;
        } catch (Exception e) {
            log.error(e.getMessage());
            return false;
        }
    }

    @Override
    public boolean disconnectWifi() {
        try {
            executeCommand("netsh wlan disconnect");
            return true;
        } catch (Exception e) {
            log.error(e.getMessage());
            return false;
        }
    }

    @Override
    public List<String> getAvailableWifiList() {
        List<String> networks = new ArrayList<>();
        String netshWlanShowNetworks = "netsh wlan show networks";
        try {
            String output = executeCommandOutput(netshWlanShowNetworks);
            // 解析输出网络列表
            String[] split = output.split("\n");
            for (String s : split) {
                if (s.trim().startsWith("SSID")) {
                    networks.add(s.split(":")[1].trim());
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return networks;
    }

    @Override
    public String getCurrentConnection() {
        try {
            String output = executeCommandOutput("netsh wlan show interfaces");
            String[] lines = output.split("\n");
            for (String line : lines) {
                if (line.trim().startsWith("SSID")) {
                    return line.split(":")[1].trim();
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return "Not connected";
    }

    private String executeCommandOutput(String netshWlanShowNetworks) throws IOException, InterruptedException {
        Process process = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", netshWlanShowNetworks});
        process.waitFor();
        try (Scanner scanner = new Scanner(process.getInputStream())) {
            return scanner.useDelimiter("\\A").hasNext() ? scanner.next() : "";
        }
    }

    private void executeCommand(String command) throws IOException, InterruptedException {
        Process process = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", command});
        process.waitFor();
    }
    //

    private Path generateWifiProfile(String ssid, String password, String encryption) throws IOException {
        String xmlContent = String.format(
                "<WLANProfile xmlns=\"http://www.microsoft.com/networking/WLAN/profile/v1\">\n" +
                        "    <name>%s</name>\n" +
                        "    <SSIDConfig>\n" +
                        "        <SSID>\n" +
                        "            <name>%s</name>\n" +
                        "        </SSID>\n" +
                        "    </SSIDConfig>\n" +
                        "    <connectionType>ESS</connectionType>\n" +
                        "    <connectionMode>auto</connectionMode>\n" +
                        "    <MSM>\n" +
                        "        <security>\n" +
                        "            <authEncryption>\n" +
                        "                <authentication>%s</authentication>\n" +
                        "                <encryption>AES</encryption>\n" +
                        "                <useOneX>false</useOneX>\n" +
                        "            </authEncryption>\n" +
                        "            <sharedKey>\n" +
                        "                <keyType>passPhrase</keyType>\n" +
                        "                <protected>false</protected>\n" +
                        "                <keyMaterial>%s</keyMaterial>\n" +
                        "            </sharedKey>\n" +
                        "        </security>\n" +
                        "    </MSM>\n" +
                        "</WLANProfile>",
                ssid, ssid, encryption, password
        );

        Path xmlPath = Files.createTempFile("wifi_profile", ".xml");
        Files.write(xmlPath, xmlContent.getBytes());
        return xmlPath;
    }
}
